package com.irdstudio.efp.nls.service.impl.sx;


import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ExternalSysException;
import com.irdstudio.basic.framework.core.exception.HangException;
import com.irdstudio.basic.framework.core.exception.OcmSystemException;
import com.irdstudio.basic.framework.core.exception.QueuePauseException;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.console.common.PrdBizEnums;
import com.irdstudio.efp.esb.common.constant.MsLoanConstant;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditBasicInfo;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditExpanding;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditMessage;
import com.irdstudio.efp.esb.service.bo.req.sx.CreditReq;
import com.irdstudio.efp.esb.service.facade.sx.CreditService;
import com.irdstudio.efp.nls.common.constant.NlsProcessBizEnums;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.common.constant.QueueTaskEnums;
import com.irdstudio.efp.nls.service.facade.NlsQueueSoltComnService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessBizService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessRuleService;
import com.irdstudio.efp.nls.service.facade.queue.NlsQueueTaskService;
import com.irdstudio.efp.nls.service.facade.sx.CreditSoltService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessRuleVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.irdstudio.basic.framework.core.util.SpringContextUtils;
import com.irdstudio.efp.console.common.ConsoleConstant;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.nls.common.constant.NlsApplyInfoEnums;
/**
 * 授信队列插槽服务实现类
  * @author heyingfeng
  * @since 2019年3月5日 上午10:26:38
  * @version 1.0
 */
public abstract class CreditSoltServiceImpl implements CreditSoltService {
	private static Logger logger = LoggerFactory.getLogger(CreditSoltServiceImpl.class);

	/**
	 * 队列插槽服务实现方法
	 * 
	 * @param nlsQueueEventVO
	 *            队列事件
	 * @throws HangException
	 * @throws BizException
	 * @throws Exception
	 * @author huangwb
	 * @since 2019年1月4日 下午5:48:22
	 * @version 1.0
	 */
	@Override
	public void execute(NlsProcessBizVO nlsProcessBizVo, NlsCreditInfoVO nlsCreditInfoVO, int soltOrder) throws QueuePauseException, HangException, BizException, Exception {
		// 预处理
		String applySeq = nlsProcessBizVo.getApplySeq();
		String soltCode = nlsProcessBizVo.getSoltCode();
		String soltName = nlsProcessBizVo.getSoltName();
		String soltService = nlsProcessBizVo.getSoltService();
		logger.info("*********************************************");
		logger.info("*            开始一个新的插槽                 * ");
		logger.info("* 申请流水号 : 【" + applySeq + "】  *");
		logger.info("* 插槽代码 : 【" + soltCode + "】  *");
		logger.info("* 插槽名称 : 【" + soltName + "】  *");
		logger.info("* 插槽服务 : 【" + soltService + "】  *");
		logger.info("*********************************************");
		try {
			// 根据插槽代码 映射
			Method methodSoltstate = nlsProcessBizVo.getClass().getMethod("setSoltState" + soltOrder, String.class);
			// 更新该插槽状态为执行中
			logger.info("申请流水号 : 【" + applySeq + "】  更新该插槽状态为执行中开始");
			methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.EXECUTING.getCode());
			nlsProcessBizService.updateByPk(nlsProcessBizVo);
			logger.info("申请流水号 : 【" + applySeq + "】  更新该插槽状态为执行中结束");
			logger.info("申请流水号 : 【" + applySeq + "】  调用该插槽的业务逻辑处理开始");
			this.doExecute(nlsProcessBizVo, nlsCreditInfoVO);
			logger.info("申请流水号 : 【" + applySeq + "】  调用该插槽的业务逻辑处理结束");
			boolean exceptionFlag = nlsProcessBizVo.isExceptionFlag();
			int hangTimes = nlsProcessBizVo.getHangTimes();
			logger.info("申请流水号 : 【" + applySeq + "】  根据异常标志【" + exceptionFlag + "】处理后续网贷任务队列信息");
			// 异常处理，执行以上服务完成后更新【 网贷业务过程 】中对应的插槽状态
			if (exceptionFlag) {
				Exception exception = nlsProcessBizVo.getExceptionMsg();
				logger.info("申请流水号 : 【" + applySeq + "】 根据异常【" + exception + "】处理后续网贷任务队列信息");

				/** 查询规则过程信息 **/
				NlsProcessRuleVO nlsProcessRuleVO = new NlsProcessRuleVO();
				nlsProcessRuleVO.setApplySeq(applySeq);
				nlsProcessRuleVO = nlsProcessRuleService.queryByPk(nlsProcessRuleVO);
				if (exception instanceof HangException) {
					logger.info("申请流水号 : 【" + applySeq + "】 处理该插槽的挂起异常开始");
					// 每次轮询队列任务表中挂起任务后再次触发挂起异常后，对挂起次数进行控制，如果大于等于三次直接失败
					hangTimes = hangTimes + 1;
					if (hangTimes > QueueTaskEnums.QueueHangTimesEnum.MAX.getTimes()) {
						logger.info("申请流水号 : 【" + applySeq + "】 异常类型为挂起异常时，该插槽挂起次数为：【" + hangTimes + "】，更新该插槽状态为失败，更新网贷任务队列中队列任务状态为执行失败， 更新申请进件信息中申请状态为拒绝开始");
						// 更新该插槽状态为失败
						methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
						nlsProcessBizVo.setHangTimes(hangTimes);
						nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.FAILURE.getCode());
						/** 设置插槽结果信息 **/
						nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
						/** 设置规则结果信息 **/
						nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
						/** 设置结果码 **/
						nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.HANG_MAX_TIMES.getRspCode());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.HANG_MAX_TIMES.getRspMsg());
						/** 设置审批状态信息为失败 **/
						nlsCreditInfoVO.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());
						
						String message = "申请流水号 : 【" + applySeq + "】 异常类型为挂起异常时，该插槽挂起次数为：【" + hangTimes + "】，更新该插槽状态为失败，更新网贷任务队列中队列任务状态为执行失败，"
								+ " 更新申请进件信息中申请状态为拒绝结束";
						logger.info(message);
						logger.info("申请流水号 : 【" + applySeq + "】执行通知授信审批失败逻辑");
						// 发送告警 @date 2019/06/19
						NlsQueueSoltComnService nlsQueueSoltComnService = (NlsQueueSoltComnService) SpringContextUtils.getBean("nlsQueueSoltComnService");
						nlsQueueSoltComnService.alarmNotice(EsbBizEnums.AlarmObjectName.OCM_REAL_TIME.getValue(), EsbBizEnums.AlarmLvl.SERIOUS.getValue(), message);
						// 通知授信审批失败
						noticeMSIfNecessary(nlsProcessBizVo,nlsCreditInfoVO);
					} else {
						/** 更新该插槽状态为挂起 **/
						logger.info("申请流水号 : 【" + applySeq + "】异常类型为挂起异常时更新该插槽状态为挂起，更新网贷任务队列中队列任务状态为挂起，更新申请进件信息中申请状态为挂起");
						methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.HANG.getCode());
						nlsProcessBizVo.setHangTimes(hangTimes);
						nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.HANG.getCode());
						/** 设置插槽结果信息 **/
						nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
						/** 设置规则结果信息 **/
						nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
						/** 设置结果码 **/
						nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.HANG.getRspCode());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.HANG.getRspMsg());
						/** 设置审批状态信息为挂起 **/
						nlsCreditInfoVO.setApprvSts(MsLoanConstant.NlsApplyStateEnum.HANG.getVALUE());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRefuseCause(exception.getMessage());
						/** 最近修改时间 **/
						nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());
						/** 最近修改时间 **/
						nlsCreditInfoVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());

						nlsProcessBizService.updateByPk(nlsProcessBizVo);
						nlsCreditInfoService.updateByPk(nlsCreditInfoVO);

						logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的挂起异常结束");
						/** 发送MQ挂起消息 add by wangyk date:20190222 **/
						producerService.sendMsg(new Message(TopicEnums.QUEUE_TASK_HANG_CREDIT_TOPIC.getTopicId(), TagEnums.TAG_QUEUE_HANG_CREDIT_TASK.getTagId(), 
								nlsCreditInfoVO.getLmtApplySeq().concat(".").concat(String.valueOf(hangTimes)),
								JSON.toJSONString(nlsCreditInfoVO).getBytes("UTF-8")),1);
						throw exception;
					}
					/**
					 * 暂停处理 wanglh4 20190516
					 */
				} else if(exception instanceof QueuePauseException) {
					logger.info("申请流水号 : 【" + applySeq + "】异常类型为暂停异常时更新该插槽状态为暂停，更新网贷任务队列中队列任务状态为暂停，更新申请进件信息中申请状态为暂停");
					methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.PAUSE.getCode());
					nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.PAUSE.getCode());
					/** 设置插槽结果信息 **/
					nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
					/** 设置规则结果信息 **/
					nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
					/** 设置结果码 **/
					nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.PAUSE.getRspCode());
					/** 设置结果信息 **/
					nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.PAUSE.getRspMsg() + "。" + exception.getMessage());
					/** 设置审批状态信息为暂停 06 **/
					nlsCreditInfoVO.setApprvSts(NlsApplyInfoEnums.NlsApplyState.PAUSE.getKey());
					/** 最近修改时间 **/
					nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());
					/** 最近修改时间 **/
					nlsCreditInfoVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());

					nlsProcessBizService.updateByPk(nlsProcessBizVo);
					nlsCreditInfoService.updateByPk(nlsCreditInfoVO);

					logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的暂停异常结束");
				} else if (exception instanceof ExternalSysException) {
					logger.info("申请流水号 : 【" + applySeq + "】 处理该插槽的外部系统异常开始");
					// 每次轮询队列任务表中外部系统异常处理任务后再次触发外部系统异常后，对外部系统异常处理次数进行控制，如果大于等于三次直接失败
					hangTimes = hangTimes + 1;
					if (hangTimes > QueueTaskEnums.QueueHangTimesEnum.MAX.getTimes()) {
						logger.info("申请流水号 : 【" + applySeq + "】 异常类型为外部异常时，该插槽处理次数为：【" + hangTimes + "】，更新该插槽状态为“失败”，更新网贷任务队列中队列任务状态为执行“作废”， 更新授信申请信息中审批状态为“通过”开始");
						methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
						nlsProcessBizVo.setHangTimes(hangTimes);
						nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.REVOKED.getCode());
						/** 设置插槽结果信息 **/
						nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
						/** 设置规则结果信息 **/
						nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
						/** 设置结果码 **/
						nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.DEAL_MAX_TIMES.getRspCode());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.DEAL_MAX_TIMES.getRspMsg());
						/** 设置审批状态信息为成功 **/
						nlsCreditInfoVO.setApprvSts(NlsApplyInfoEnums.NlsApplyState.PASS.getKey());
						
						String message = "申请流水号 : 【" + applySeq + "】 异常类型为外部异常时，该插槽处理次数为：【" + hangTimes + "】，更新该插槽状态为“失败”，更新网贷任务队列中队列任务状态为执行“作废”， "
								+ "更新授信申请信息中审批状态为“通过”结束";
						logger.info(message);
						
						// 更新授信额度状态为“已失效” @date 2019/06/26
						this.updLmtPrdCont(applySeq);
						
						// 发送告警 @date 2019/06/19
						NlsQueueSoltComnService nlsQueueSoltComnService = (NlsQueueSoltComnService) SpringContextUtils.getBean("nlsQueueSoltComnService");
						nlsQueueSoltComnService.alarmNotice(EsbBizEnums.AlarmObjectName.OCM_REAL_TIME.getValue(), EsbBizEnums.AlarmLvl.SERIOUS.getValue(), message);
						
					} else {
						/** 更新该插槽状态为外部系统 **/
						logger.info("申请流水号 : 【" + applySeq + "】异常类型为外部系统异常时更新该插槽状态为外部系统，更新网贷任务队列中队列任务状态为外部系统，更新申请进件信息中申请状态为外部系统");
						methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.HANG.getCode());
						nlsProcessBizVo.setHangTimes(hangTimes);
						nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.HANG.getCode());
						/** 设置插槽结果信息 **/
						nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
						/** 设置规则结果信息 **/
						nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
						/** 设置结果码 **/
						nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.HANG.getRspCode());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.HANG.getRspMsg());
						/** 设置审批状态信息为“挂起”**/
						nlsCreditInfoVO.setApprvSts(NlsApplyInfoEnums.NlsApplyState.HANG.getKey());
						/** 设置结果信息 **/
						nlsCreditInfoVO.setRefuseCause(exception.getMessage());
						/** 最近修改时间 **/
						nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());
						/** 最近修改时间 **/
						nlsCreditInfoVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());

						nlsProcessBizService.updateByPk(nlsProcessBizVo);
						nlsCreditInfoService.updateByPk(nlsCreditInfoVO);

						logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的外部系统异常结束");
						
						// 在重新发送消息时，给异常位置标识赋值  @date 2019/06/29
						nlsCreditInfoVO.setExceptionLocation(((ExternalSysException) ((Object)exception)).getErrorCode());
						// 延迟5s重新发送消息，主题是“挂起”
						producerService.sendMsg(new Message(TopicEnums.QUEUE_TASK_HANG_CREDIT_TOPIC.getTopicId(), TagEnums.TAG_QUEUE_HANG_CREDIT_TASK.getTagId(), 
								nlsCreditInfoVO.getLmtApplySeq().concat(".").concat(String.valueOf(hangTimes)),
								JSON.toJSONString(nlsCreditInfoVO).getBytes("UTF-8")), 5);
						throw exception;
					}
				} else if (exception instanceof OcmSystemException) {
					logger.info("申请流水号 : 【" + applySeq + "】 处理该插槽的系统自身异常开始，更新该插槽状态为“失败”，更新网贷任务队列中队列任务状态为执行“失败”， 更新授信申请信息中审批状态为“通过”开始");
					methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.SUCCESS.getCode());
					nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.FAILURE.getCode());
					/** 设置插槽结果信息 **/
					nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
					/** 设置规则结果信息 **/
					nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
					/** 设置结果码 **/
					nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspCode());
					/** 设置结果信息 **/
					nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspMsg());
					/** 设置审批状态信息为通过 **/
					nlsCreditInfoVO.setApprvSts(NlsApplyInfoEnums.NlsApplyState.PASS.getKey());
					logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的系统自身异常结束");
					
					// 更新授信额度状态为“已失效” @date 2019/06/26
					this.updLmtPrdCont(applySeq);
					
				} else if (exception instanceof BizException) {
					logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的业务异常开始，更新该插槽状态为失败， 更新网贷任务队列中队列任务状态为执行失败，更新申请进件信息中申请状态为拒绝");
					// 更新该插槽状态为失败
					methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
					nlsProcessBizVo.setHangTimes(hangTimes);
					nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.FAILURE.getCode());
					/** 设置插槽结果信息 **/
					nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
					/** 设置规则结果信息 **/
					nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
					/** 设置结果码 **/
					nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspCode());
					/** 设置结果信息 **/
					nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspMsg());
					/** 设置审批状态信息为失败 **/
					nlsCreditInfoVO.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());
					// 通知授信审批失败
					noticeMSIfNecessary(nlsProcessBizVo,nlsCreditInfoVO);
					logger.info("申请流水号 : 【" + applySeq + "】处理该插槽的业务异常结束");
				} else {
					logger.info("申请流水号 : 【" + applySeq + "处理该插槽的其它异常开始，更新该插槽状态为失败， 更新网贷任务队列中队列任务状态为执行失败，更新申请进件信息中申请状态为拒绝");
					// 更新该插槽状态为失败
					methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.FAILURE.getCode());
					nlsProcessBizVo.setHangTimes(hangTimes);
					nlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.FAILURE.getCode());
					/** 设置插槽结果信息 **/
					nlsCreditInfoVO.setSoltResultDetails(JSONObject.toJSONString(nlsProcessBizVo));
					/** 设置规则结果信息 **/
					nlsCreditInfoVO.setRuleResultDetails(JSONObject.toJSONString(nlsProcessRuleVO));
					/** 设置结果码 **/
					nlsCreditInfoVO.setRspCode(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspCode());
					/** 设置结果信息 **/
					nlsCreditInfoVO.setRspMsg(NlsProcessBizEnums.RspInfoEnum.FAILURE.getRspMsg());
					/** 设置审批状态信息为失败 **/
					nlsCreditInfoVO.setApprvSts(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());
					// 通知授信审批失败
					noticeMSIfNecessary(nlsProcessBizVo,nlsCreditInfoVO);
					logger.info("申请流水号 : 【" + applySeq + "处理该插槽的其它异常结束");
				}
				/** 设置结果信息 **/
				nlsCreditInfoVO.setRefuseCause(exception.getMessage());
				
				/** 设置拒绝原因码、  原因描述  @date 2019/05/28 */   // 暂时注释，因为超时异常无法捕获，需求需要重审  TODO
//				if(!(exception instanceof QueuePauseException)) {
//					if(StringUtil.isStrNotEmpty(nlsProcessBizVo.getRejectCode()) && !NlsApplyInfoEnums.RejectCode.MSG16.getKey().equals(nlsProcessBizVo.getRejectCode())) {
//						nlsCreditInfoVO.setBdReasonCode(nlsProcessBizVo.getRejectCode());
//						nlsCreditInfoVO.setBdReasonMsg(NlsApplyInfoEnums.RejectCode.getValue(nlsProcessBizVo.getRejectCode()));
//					}else {
//						nlsCreditInfoVO.setBdReasonCode(NlsApplyInfoEnums.RejectCode.MSG16.getKey());
//						nlsCreditInfoVO.setBdReasonMsg(NlsApplyInfoEnums.RejectCode.getValue(NlsApplyInfoEnums.RejectCode.MSG16.getKey()));
//					}
//				}
//				
				/** 最近修改时间 **/
				nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());
				/** 最近修改时间 **/
				nlsCreditInfoVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());
				/** 审批时间 **/
				nlsCreditInfoVO.setApprvDate(DateUtility.getCurrDate());
				
				nlsProcessBizService.updateByPk(nlsProcessBizVo);
				nlsCreditInfoService.updateByPk(nlsCreditInfoVO);

				throw exception;
			}else if("1".equals(nlsProcessBizVo.getSoltName30())){
				nlsCreditInfoVO.setApprvSts(ConsoleConstant.NLSCREDIT_REJECT);
				/** 最近修改时间 **/
				nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());
				nlsProcessBizVo.setSoltName30("");
				/** 最近修改时间 **/
				nlsCreditInfoVO.setLastUpdateTime(DateUtility.getCurrAppDateTimeString());
				nlsCreditInfoService.updateByPk(nlsCreditInfoVO);
			} else {
				logger.info("申请流水号 : 【" + applySeq + "该插槽的无异常开始，更新该插槽状态为成功，此处队列任务表和进件申请表的数据需要等插槽全部执行完成后才更新");
				// 更新该插槽状态为成功
				methodSoltstate.invoke(nlsProcessBizVo, PrdAdaptedSoltEnums.SoltProcessStateEnum.SUCCESS.getCode());
				nlsProcessBizVo.setHangTimes(QueueTaskEnums.QueueHangTimesEnum.INITIALIZE.getTimes());
				// 此处队列任务表和进件申请表的数据需要等插槽全部执行完成后才更新
				logger.info("申请流水号 : 【" + applySeq + "该插槽的无异常结束");
			}
			nlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());// 最近修改时间
			// 最近修改时间
			nlsProcessBizService.updateByPk(nlsProcessBizVo);
		} catch (QueuePauseException e) {
			logger.error("队列插槽服务中申请流水号:【" + applySeq + "】的处理暂停异常信息为：" + e.getMessage());
			throw new QueuePauseException();
		} catch (HangException e) {
			logger.error("队列插槽服务中申请流水号:【" + applySeq + "】的处理挂起异常信息为：" + e.getMessage());
			throw new HangException();
		} catch (BizException e) {
			logger.error("队列插槽服务中申请流水号:【" + applySeq + "】的业务异常信息为：" + e.getMessage());
			throw new BizException();
		} catch (Exception e) {
			logger.error("队列插槽服务中申请流水号:【" + applySeq + "】的其他异常信息为：" + e.getMessage());
			throw new Exception();
		}

	}

	/**
	 * 供插槽实现的抽象方法
	 * 
	 * @param nlsQueueEventVO
	 *            队列事件
	 * @author huangwb
	 * @since 2019年1月4日 下午5:37:21
	 * @version 1.0
	 */
	protected abstract void doExecute(NlsProcessBizVO nlsProcessBizVo, NlsCreditInfoVO nlsCreditInfoVO) throws Exception;

	
	/**
	 * 通知审批失败
	  * @param nlsProcessBizVo
	  * @throws Exception
	  * @author heyingfeng
	  * @since 2019年3月5日 上午11:40:34
	  * @version 1.0
	 */
	private void noticeMSIfNecessary(NlsProcessBizVO nlsProcessBizVo, NlsCreditInfoVO nlsCreditInfoVO) throws Exception {
		try {
			if (nlsProcessBizVo.getPrdId().equals(PrdBizEnums.PrdCodeEnum.PRD_CODE_MYD.getValue()) || nlsProcessBizVo.getPrdId().equals(PrdBizEnums.PrdCodeEnum.PRD_CODE_ZXD.getValue())) {
				CreditReq creditReq = new CreditReq();
				CreditMessage creditMessage = new CreditMessage();
				CreditBasicInfo creditBasicInfo = new CreditBasicInfo();
				CreditExpanding creditExpanding = new CreditExpanding();
				creditReq.setProdCd(nlsCreditInfoVO.getPrdCode());//产品代码
				creditReq.setRqsFlg(nlsCreditInfoVO.getBdReqSn());//请求方需要保证永远唯一 响应方据此判断是否重复请求
				creditReq.setRetCd(MsLoanConstant.RetCodeEnum.SUCCESS.VALUE);
				creditReq.setTxnMd("async");//交易模式
				creditReq.setRepeatRqsBss(nlsCreditInfoVO.getBdReqSn());//重复请求依据
				/** Message	业务数据 start */
				creditMessage.setSessionId(nlsCreditInfoVO.getLmtApplySeq());// 交易流水号
				creditMessage.setEvTp("apply");//事务类型
				creditMessage.setEvID(nlsCreditInfoVO.getBdTransactionId());//事务ID
				creditMessage.setRqsTmstmp(new Date().getTime()+"");//时间戳
				/** BasicInfo	基本信息 start */
				creditBasicInfo.setIDCertNo(nlsCreditInfoVO.getCertCode());//身份证号
				creditBasicInfo.setBankCardNo(nlsCreditInfoVO.getRecvAccount());//银行卡号
				creditBasicInfo.setCustNm(nlsCreditInfoVO.getCusName());//客户姓名
				creditBasicInfo.setMblNo(nlsCreditInfoVO.getIndivMobile());//手机号码
				/** BasicInfo	基本信息 end */
				/** Expanding	定制域 start */
				creditExpanding.setCrdtLmt(nlsCreditInfoVO.getApplyAmt()+"");	//授信额度
				creditExpanding.setCrdtDt(nlsCreditInfoVO.getApplyTerm());	//授信有效期
				creditExpanding.setInstRsnCd(nlsCreditInfoVO.getBdReasonCode());	//机构原因码
				creditExpanding.setInstRsnCdRmk(nlsCreditInfoVO.getBdReasonMsg());	//机构原因码说明
				creditExpanding.setInstPolcyCd(MsLoanConstant.RisCodeEnum.FAILURE.VALUE);	//机构策略码
				/** Expanding	定制域 end */
				creditMessage.setBasicInfo(creditBasicInfo);
				creditMessage.setExpanding(creditExpanding);
				creditReq.setMessage(creditMessage);
				creditService.creditNotify(creditReq);// 发送请求
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

	}
	/**
	 * 需求编号：【2019D0519】（业务提的需求编号）
	 * 问题编号：【xxxxxxx】（若不是因为修复问题而新增该类，则留空）
	 * 开发人员：qiuyf
	 * 创建日期：2019年6月26日 上午10:51:31
	 * 功能描述：更新授信额度状态为“已失效”
	 */
	private void updLmtPrdCont(String lmtApplySeq) {
		LmtPrdContVO lmtPrdContVO =  lmtPrdContService.qryLmtPrdContByLmtApplySeq(lmtApplySeq);
		if(Objects.isNull(lmtPrdContVO)) {
			logger.error("通过授信申请流水号【" + lmtApplySeq + "】查询到的授信协议信息为空！");
		}
		//设置额度状态为“已失效”
		lmtPrdContVO.setLmtStatus(ConsoleConstant.LIMIT_STS_03);
		int num = lmtPrdContService.updateByPk(lmtPrdContVO);
		if(num < 0) {
			logger.error("更新额度状态为“有效”失败，入参数据为：" + JSON.toJSONString(lmtPrdContVO));
		}
	}

	@Autowired
	@Qualifier("nlsQueueTaskService")
	private NlsQueueTaskService nlsQueueTaskService;
	@Autowired
	@Qualifier("nlsProcessBizService")
	private NlsProcessBizService nlsProcessBizService;
	@Autowired
	@Qualifier("nlsCreditInfoService")
	private NlsCreditInfoService nlsCreditInfoService;
	@Autowired
	@Qualifier("creditService")
	private CreditService creditService;
	@Autowired
	@Qualifier("nlsProcessRuleService")
	private NlsProcessRuleService nlsProcessRuleService;
	@Autowired
	@Qualifier("producerService")
	private MQProducerMessageClient producerService;
	@Autowired
	@Qualifier("lmtPrdContService")
	private LmtPrdContService lmtPrdContService;
}
